// import { glob } from 'glob'
// const testFiles = glob.sync("**/*.test.js")
// console.log('testFiles', testFiles);

import JestHasteMap from "jest-haste-map";
import { cpus } from "os";
import { dirname, relative, join } from "path";
import { fileURLToPath } from "url";
import fs from 'fs'
import chalk from "chalk";
import { Worker } from 'jest-worker'

const root = dirname(fileURLToPath(import.meta.url));

const hasteMapOptions = {
    extensions: ["js"], // 只遍历 .js 文件
    maxWorkers: cpus().length, // 并行处理所有可用的 CPU
    name: "best", // 用于缓存的名称
    platforms: [], // 只针对 React Native 使用，这里不需要
    rootDir: root, // 项目的根目录
    roots: [root], // 可以用于只搜索 `rootDir` 中的某个子集文件
};

const hasteMap = new JestHasteMap.default(hasteMapOptions)

// 这行代码是可选的，用于在 jest-haste-map 版本 28 或更高版本中设置缓存路径。
await hasteMap.setupCachePath(hasteMapOptions);

const { hasteFS } = await hasteMap.build();

// 获取所有 测试文件
// 如果用户传入了第二个参数，那么我们就读取第二个参数所指定的文件
const testFiles = hasteFS.matchFilesWithGlob([
    process.argv[2] ? `**/${process.argv[2]}*` : "**/*.test.js",
]);
// await Promise.all(
//     Array.from(testFiles).map(async (testFile) => {
//         const code = await fs.promises.readFile(testFile, "utf8");
//         console.log(testFile + ":\n" + code);
//     })
// );

const worker = new Worker(join(root, "worker.js"), {
    enableWorkerThreads: true, // 允许多线程
})

let hasFailded = false;
await Promise.all(
    Array.from(testFiles).map(async (testFile) => {
        const { success, testResults, errMessage } = await worker.runTest(testFile)
        const status = success
            ? chalk.green.inverse.bold(" 成功 ")
            : chalk.red.inverse.bold(" 失败 ");

        console.log(status + " " + chalk.dim(relative(root, testFile)));

        if (!success) {
            hasFailded = true;
            // 如果测试失败
            if (testResults) {
                testResults
                    .filter(result => result.errors.length)
                    .forEach(result => console.log(
                        // Skip the first part of the path which is an internal token.
                        result.testPath.slice(1).join(' ') + '\n' + result.errors[0],
                    ),)
            } else if (errMessage) {
                console.log(" " + errMessage);
            }
        }
    })
)

worker.end()


// 给予失败的信息提示
if (hasFailded) {
    console.log("\n" + chalk.red.bold("测试用例有失败的案例，请检查您的代码"));
    process.exitCode = 1;
}
